package jam4j.util;

import java.util.Collection;

public abstract class Throwables {
    private Throwables() { }
    
    public interface ExceptionCapturer<X extends Throwable> {
        void capture(X exception);
    }
    
    public static <X extends Throwable> ExceptionCapturer<X>
            captureInto(final Collection<? super X> collection) {
        return new ExceptionCapturer<X>() {
            public void capture(X exception) {
                collection.add(exception);
            }
        };
    }
    
    public static <X extends Throwable> void capturing(
            FallibleThunk<?, ? extends X> thunk,
            Class<X> exceptionType,
            ExceptionCapturer<? super X> capturer) {
        try {
            thunk.call();
        } catch (Throwable e) {
            if (exceptionType.isInstance(e))
                capturer.capture(exceptionType.cast(e));
            else if (e instanceof RuntimeException)
                throw (RuntimeException) e;
            else if (e instanceof Error)
                throw (Error) e;
            else
                // Shouldn't be possible, as the thunk can only throw X
                throw new RuntimeException(
                        "Unexpected exception thrown by thunk", e);
        }
    }
}
